001    /* EVolve - an Extensible Software Visualization Framework
002     * Copyright (C) 2001-2002 Qin Wang
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Library General Public
006     * License as published by the Free Software Foundation; either
007     * version 2 of the License, or (at your option) any later version.
008     *
009     * This library is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Library General Public License for more details.
013     *
014     * You should have received a copy of the GNU Library General Public
015     * License along with this library; if not, write to the
016     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017     * Boston, MA 02111-1307, USA.
018     */
019    
020    /*
021     * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022     */
023    
024    package EVolve.visualization;
025    
026    import EVolve.*;
027    import EVolve.util.phasedetectors.*;
028    import EVolve.exceptions.NoDataPlotException;
029    import EVolve.visualization.VizFactory.VisualizationFactory;
030    import EVolve.visualization.XYViz.XYVisualization;
031    import EVolve.data.*;
032    import java.awt.*;
033    import java.awt.event.*;
034    import java.util.*;
035    import javax.swing.*;
036    
037    public class VisualizationManager {
038        private VisualizationFactory[] factory;
039        private ArrayList visualizationList;
040        private ArrayList toVisualize;
041        private Visualization[][] visualization;
042    
043        private JDialog dialog;
044        private JList listVisualization;
045        private DefaultListModel model;
046    
047        private boolean phaseDetectorEnabled;
048        private PhaseOperation phaseOperation;
049    
050        public VisualizationManager(VisualizationFactory[] factory) {
051            this.factory = factory;
052            this.visualizationList = new ArrayList();
053            this.toVisualize = new ArrayList();
054            this.dialog = null;
055            phaseDetectorEnabled = false;
056            phaseOperation = new PhaseOperation();
057        }
058    
059        public void init() {
060            ArrayList newVisualizationList = new ArrayList();
061            ArrayList newToVisualize = new ArrayList();
062    
063            for (int i=0; i<visualizationList.size(); i++) {
064                Visualization visual = (Visualization)visualizationList.get(i);
065                if (visual.getDataSourceId() != Scene.getDataSourceManager().getCurrentDataSourceId())
066                    newVisualizationList.add(visual);
067            }
068    
069            for (int i=0; i<toVisualize.size(); i++) {
070                Visualization visual = (Visualization)toVisualize.get(i);
071                if (visual.getDataSourceId() != Scene.getDataSourceManager().getCurrentDataSourceId())
072                    newToVisualize.add(visual);
073            }
074            visualizationList = newVisualizationList;
075            toVisualize = newToVisualize;
076        }
077    
078        private void createDialog() {
079            dialog = new JDialog(Scene.getFrame(), "Select Visualizations", true);
080            model = new DefaultListModel();
081            listVisualization = new JList(model);
082            listVisualization.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
083    
084            JScrollPane scrollPane = new JScrollPane(listVisualization);
085            scrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Choose visualizations"));
086            dialog.getContentPane().add(scrollPane, BorderLayout.CENTER);
087    
088            JPanel panelButton = new JPanel(new FlowLayout());
089            dialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
090    
091            JButton buttonApply = new JButton("Apply");
092            buttonApply.addActionListener(new ActionListener() {
093                public void actionPerformed(ActionEvent e) {
094                    dialogApply();
095                }
096            });
097            panelButton.add(buttonApply);
098    
099            JButton buttonCancel = new JButton("Cancel");
100            buttonCancel.addActionListener(new ActionListener() {
101                public void actionPerformed(ActionEvent e) {
102                    dialogCancel();
103                }
104            });
105            panelButton.add(buttonCancel);
106        }
107    
108        public String[] getFactoryName() {
109            ArrayList list = new ArrayList();
110            for (int i = 0; i < factory.length; i++) {
111                ElementDefinition[] temp = Scene.getDataManager().getElementDefinition(factory[i].getDefinition());
112                if (temp.length != 0) {
113                    list.add(factory[i]);
114                }
115            }
116    
117            String[] returnVal = new String[list.size()];
118            for (int i = 0; i < returnVal.length; i++) {
119                returnVal[i] = ((VisualizationFactory)(list.get(i))).getName();
120            }
121            return returnVal;
122        }
123    
124        public Visualization newVisualization(String name) {
125            Visualization newVisualization = null;
126    
127            for (int i = 0; i < factory.length; i++) {
128                if (name.equals(factory[i].getName())) {
129                    newVisualization = factory[i].createVisualization();
130                    newVisualization.setName(name);
131                    newVisualization.setDataSourceId(Scene.getDataSourceManager().getCurrentDataSourceId());
132                    newVisualization.setFactory(factory[i]);
133                    newVisualization.setDefinition(factory[i].getDefinition());
134                    break;
135                }
136            }
137            visualizationList.add(newVisualization);
138            toVisualize.add(newVisualization);
139            Scene.getUIManager().addVisualization(newVisualization);
140            return newVisualization;
141        }
142    
143        public void removeVisualization(Visualization visualization) {
144            visualizationList.remove(visualization);
145            toVisualize.remove(visualization);
146        }
147    
148        public void preVisualize() {
149            if (dialog == null) {
150                createDialog();
151            }
152    
153            int[] selected = new int[toVisualize.size()];
154            int selectedCounter = 0;
155    
156            model.removeAllElements();
157    
158            for (int i = 0; i < visualizationList.size(); i++) {
159                model.addElement(((Visualization)(visualizationList.get(i))).getName());
160                if (toVisualize.indexOf(visualizationList.get(i)) != -1) {
161                    selected[selectedCounter] = i;
162                    selectedCounter++;
163                }
164            }
165    
166            listVisualization.setSelectedIndices(selected);
167    
168            Scene.getUIManager().showDialog(dialog, 270, 360);
169        }
170    
171        public void receiveEvent(EVolve.data.Event event) {
172            int currentDsourceId = Scene.getDataSourceManager().getCurrentDataSourceId();
173            for (int i = 0; i < visualization[event.getType()].length; i++) {
174                int dataSourceId = visualization[event.getType()][i].getDataSourceId();
175                if (dataSourceId == currentDsourceId)
176                    visualization[event.getType()][i].receiveElement(event);
177            }
178        }
179    
180        public void visualize() {
181            try {
182                for (int i = 0; i < visualization.length; i++) {
183                    for (int j = 0; j < visualization[i].length; j++) {
184                        int dataSourceId = visualization[i][j].getDataSourceId();
185                        if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId())
186                                continue;
187    
188                        for (int k = 0; k < visualization[i][j].getDimension().length; k++) {
189                            if (visualization[i][j].getDimension()[k] instanceof ReferenceDimension) {
190                                ((ReferenceDimension)(visualization[i][j].getDimension()[k])).visualize();
191                            }
192                        }
193                        visualization[i][j].visualize();
194                        visualization[i][j].updateMenu();
195                        visualization[i][j].enableSortMenu();
196                    }
197                }
198            } catch (NoDataPlotException e) { //a non-fatal exception, show message and then ignore it
199                Scene.showErrorMessage(e.getMessage());
200            }
201    
202        }
203    
204        private void dialogApply() {
205            dialog.setVisible(false);
206    
207            toVisualize.clear();
208    
209            int[] selected = listVisualization.getSelectedIndices();
210    
211            for (int i = 0; i < selected.length; i++) {
212                toVisualize.add(visualizationList.get(selected[i]));
213            }
214    
215            if (toVisualize.size() != 0) {
216                prepareListToBeVisualized();
217                Scene.visualize();
218            }
219        }
220    
221        private void dialogCancel() {
222            dialog.setVisible(false);
223        }
224    
225        public ArrayList getVisualizationType() {
226            ArrayList returnVal = new ArrayList();
227            for (int i = 0; i < visualizationList.size(); i++) {
228                String s = "" + ((Visualization)(visualizationList.get(i))).getSubjectDefinition().getType() + "";
229                if (returnVal.indexOf(s) == -1) {
230                    returnVal.add(s);
231                }
232            }
233    
234            return returnVal;
235        }
236    
237        public VisualizationFactory getFactory(String name) {
238            VisualizationFactory retFac = null;
239            for (int i = 0; i < factory.length; i++) {
240                if (name.equals(factory[i].getName())) {
241                    retFac = factory[i];
242                    break;
243                }
244            }
245            return retFac;
246        }
247    
248        public void autoPreVisualize(HashMap conf) {
249            Visualization visual= (Visualization)visualizationList.get(0);
250    
251            visual.autoUpdateConfiguration(conf);
252    
253            toVisualize.clear();
254    
255            toVisualize.add(visualizationList.get(0));
256    
257            if (toVisualize.size() != 0) {
258                prepareListToBeVisualized();
259            }
260        }
261    
262        public void autoSaveResult(String path, String dataFn) {
263            Visualization visual= (Visualization)visualizationList.get(0);
264            visual.autoSave(path,dataFn);
265        }
266    
267        public ArrayList getVisualizationList() {
268            return visualizationList;
269        }
270    
271        public void prepareListToBeVisualized() {
272            visualization = new Visualization[Scene.getDataManager().getElementDefinition().length][];
273            for (int i = 0; i < visualization.length; i++) {
274                ArrayList list = new ArrayList();
275                for (int j = 0; j < toVisualize.size(); j++) {
276                    if (((Visualization)(toVisualize.get(j))).getSubjectDefinition().getType() == i) {
277                        list.add(toVisualize.get(j));
278                    }
279                }
280                visualization[i] = new Visualization[list.size()];
281                for (int j = 0; j < visualization[i].length; j++) {
282                    visualization[i][j] = (Visualization)(list.get(j));
283                    visualization[i][j].preVisualize();
284                    for (int k = 0; k < visualization[i][j].getDimension().length; k++) {
285                        visualization[i][j].getDimension()[k].preVisualize();
286                    }
287                }
288            }
289        }
290    
291        // following methods are used in predefined visualization
292        public void cleanup() {
293            Scene.getUIManager().clearWindowsList();
294            for (int i=0; i<visualizationList.size(); i++) {
295                Visualization visual =(Visualization) visualizationList.get(i);
296                visual.getWindow().dispose();
297            }
298            init();
299        }
300    
301        // following methods are used in linked visualization
302        public void addAllVisualizations() {
303            toVisualize.clear();
304            for (int i=0; i<visualizationList.size(); i++)
305                toVisualize.add(visualizationList.get(i));
306        }
307    
308        public void prepareForLinkedViz(ArrayList viz,int beginRepaint) {
309            toVisualize.clear();
310    
311            for (int i=beginRepaint; i< viz.size(); i++) {
312                toVisualize.add(viz.get(i));
313            }
314            if (toVisualize.size() != 0)
315                prepareListToBeVisualized();
316        }
317    
318        public Visualization prepareForAsynOverlapViz(String name) {
319            Visualization newVisualization = null;
320    
321            for (int i = 0; i < factory.length; i++) {
322                if (name.equals(factory[i].getName())) {
323                    newVisualization = factory[i].createVisualization();
324                    newVisualization.setName(name);
325                    newVisualization.setFactory(factory[i]);
326                    newVisualization.setDefinition(factory[i].getDefinition());
327                    break;
328                }
329            }
330            return newVisualization;
331        }
332    
333        public void visualizeNow() {
334            Visualization visual = getActiveVisualization();
335    
336            if (visual != null) {
337                int dataSourceId = visual.getDataSourceId();
338    
339                if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
340                    Scene.getUIManager().selectDataSource(dataSourceId);
341                }
342    
343                visualization = new Visualization[Scene.getDataManager().getElementDefinition().length][];
344                for (int i = 0; i < visualization.length; i++) {
345                    ArrayList list = new ArrayList();
346                    if (visual.getSubjectDefinition().getType() == i) {
347                        list.add(visual);
348                    }
349                    visualization[i] = new Visualization[list.size()];
350                    for (int j = 0; j < visualization[i].length; j++) {
351                        visualization[i][j] = (Visualization)(list.get(j));
352                        visualization[i][j].preVisualize();
353                        for (int l = 0; l < visualization[i][j].getDimension().length; l++) {
354                            (visualization[i][j].getDimension()[l]).preVisualize();
355                        }
356                    }
357                }
358    
359                Scene.visualize();
360            }
361       }
362    
363        public void cloneVisualization() {
364            Visualization visual = getActiveVisualization();
365    
366            if (visual == null) return;
367    
368            HashMap configuration = visual.getCurrentConfigure();
369    
370            Visualization newViz = (Visualization)visual.clone();
371    
372            visualizationList.add(newViz);
373            toVisualize.add(newViz);
374            Scene.getUIManager().addVisualization(newViz);
375            newViz.setName(visual.getName()+"- cloned");
376            newViz.autoUpdateConfiguration(configuration);
377    
378            try {
379                newViz.getWindow().setBounds(visual.getWindow().getBounds());
380                newViz.visualize();
381                newViz.updateMenu();
382                newViz.enableSortMenu();
383            } catch (Exception e) {
384                // when the clone object is not visualized yet, this
385                // harmless exception happens.
386            }
387        }
388    
389        public Visualization getActiveVisualization() {
390    
391            Visualization visual = null;
392    
393            for (int i=0; i<visualizationList.size(); i++) {
394                visual = (Visualization)visualizationList.get(i);
395                if (visual.getWindow().isSelected()) break;
396            }
397    
398            return visual;
399        }
400    
401        public void enablePhaseDetector(boolean enabled) {
402            phaseDetectorEnabled = enabled;
403            for (int i=0; i<visualizationList.size(); i++) {
404                Visualization visual = (Visualization)visualizationList.get(i);
405    
406                if (visual instanceof TableViz) continue;
407    
408                ((XYVisualization)visual).enablePhaseDetector(enabled);
409            }
410        }
411    
412        public boolean isPhaseDetectorEnabled() {
413            return phaseDetectorEnabled;
414        }
415    
416        public void refreshPhases() {
417            for (int i=0; i<visualizationList.size(); i++) {
418                Visualization visual = (Visualization)visualizationList.get(i);
419                visual.sort();
420            }
421    
422        }
423    
424        public PhaseOperation getPhaseOperation() {
425            return phaseOperation;
426        }
427    }
428